import { PKMapData } from "@/parkour/maps";
import { EasingType, StructureAnimationMode, world } from "@minecraft/server";
import { Dimensions } from "@sapi-game/constants";
import { Game, GameComponent, regionHelper } from "@sapi-game/main";
import { Duration } from "@sapi-game/utils";
import {
    CameraPreset,
    EffectIds,
    EntityTypeIds,
} from "@sapi-game/utils/vanila-data";
import { PKLoadState } from "./loadState";

export class PKMapLoader extends GameComponent<PKLoadState> {
    override onAttach(): void {
        this.subscribe(
            Game.events.interval,
            this.interval.bind(this),
            new Duration(20)
        );
        //地图加载
        this.runner.run(async (r) => {
            await r.do(() => this.fillAir());
            await r.wait(2);
            r.do(() => this.killEntity());
            await r.do(() => this.fillAir());
            await r.wait(2);
            r.do(() => {
                this.context.groupSet.forEach((p) =>
                    p.player.camera.setCamera(CameraPreset.Free, {
                        easeOptions: {
                            easeTime: 4,
                            easeType: EasingType.InCubic,
                        },
                        location: { x: 721.67, y: -15.31, z: 574.29 },
                        facingLocation: { x: 734, y: -27, z: 589 },
                    })
                );
            });
            await r.wait(1);
            r.do(() => this.killEntity());
            r.do(() => this.loadMap(this.context.map, 5));
            await r.wait(120);
            r.do(() => {
                // this.killEntity();
                this.context.groupSet.runCommand("title @s title 地图重置完成");
            });
            await r.wait(20);
            //转移到下一状态
            r.do(() => this.state.toNext());
        });
    }

    interval() {
        this.context.groupSet.forEach((p) => {
            p.player.addEffect(EffectIds.Invisibility, 20, {
                showParticles: false,
            });
            p.player.addEffect(EffectIds.Regeneration, 20, {
                showParticles: false,
            });
            p.player.addEffect(EffectIds.Slowness, 20, {
                showParticles: false,
                amplifier: 10,
            });
        });
    }

    override onDetach(): void {
        this.context.groupSet.forEach((p) => {
            p.player.runCommand("effect @s clear");
            p.player.camera.clear();
        });
        super.onDetach();
    }

    killEntity() {
        this.state.gameRegion
            .getEntitesInRegion({ excludeTypes: [EntityTypeIds.Player] })
            .forEach((e) => e.remove());
    }

    fillAir() {
        const gen = regionHelper.fillGenerator(this.state.gameRegion, "air");
        const { promise } = this.runner.runJob(gen);
        return promise;
    }

    async loadMap(data: PKMapData, time: number) {
        world.structureManager.place(
            data.structureName,
            Dimensions.Overworld,
            this.context.red.base,
            {
                animationMode: StructureAnimationMode.Blocks,
                animationSeconds: time,
            }
        );
        world.structureManager.place(
            data.structureName,
            Dimensions.Overworld,
            this.context.blue.base,
            {
                animationMode: StructureAnimationMode.Blocks,
                animationSeconds: time,
            }
        );
    }
}
